home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
551-575
/
disk_556
/
scheme2c
/
scheme-src.lzh
/
scrt
/
scexpanders2.sc
< prev
next >
Wrap
Text File
|
1991-10-11
|
8KB
|
192 lines
;;; This module contains the basic macro expanders required by Scheme.
;* Copyright 1989 Digital Equipment Corporation
;* All Rights Reserved
;*
;* Permission to use, copy, and modify this software and its documentation is
;* hereby granted only under the following terms and conditions. Both the
;* above copyright notice and this permission notice must appear in all copies
;* of the software, derivative works or modified versions, and any portions
;* thereof, and both notices must appear in supporting documentation.
;*
;* Users of this software agree to the terms and conditions set forth herein,
;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
;* right and license under any changes, enhancements or extensions made to the
;* core functions of the software, including but not limited to those affording
;* compatibility with other hardware or software environments, but excluding
;* applications which incorporate this software. Users further agree to use
;* their best efforts to return to Digital any such changes, enhancements or
;* extensions that they make and inform Digital of noteworthy uses of this
;* software. Correspondence should be provided to Digital at:
;*
;* Director of Licensing
;* Western Research Laboratory
;* Digital Equipment Corporation
;* 100 Hamilton Avenue
;* Palo Alto, California 94301
;*
;* This software may be distributed (but not offered for sale or transferred
;* for compensation) to third parties, provided such third parties agree to
;* abide by the terms and conditions of this notice.
;*
;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
;* SOFTWARE.
(module scexpanders2 (top-level))
(include "repdef.sc")
;;; (let ((var init)...) body) ==> ((lambda (var...) body) init...)
;;;
;;; (let var ((v init) ...) body) ==> (letrec ((var (lambda (...) body)))
;;; (var init ...))
;;; LET is expanded into a lambda expression. While this may make the
;;; resulting expanded code more difficult to read, later analysis is eased
;;; because there are fewer forms. Variable order is retained to make the
;;; resulting tree easier to compare against the original tree.
;;;
;;; A "named let" is expanded into the appropriate letrec expression. That in
;;; turn is expanded into the appropriate lambda expression when the letrec
;;; is expanded.
(define (LET-MACRO exp)
(cond ((and (islist exp 3) (islist (cadr exp) 0))
(do ((var-inits (cadr exp) (cdr var-inits))
(vars '())
(inits '()))
((or (not (pair? var-inits))
(not (islist (car var-inits) 2 2))
(not (symbol? (caar var-inits))))
(if var-inits
(error 'let "Illegal form: ~s" exp)
`((lambda ,(reverse vars) ,@(cddr exp))
,@(reverse inits))))
(set! vars (cons (caar var-inits) vars))
(set! inits (cons (cadar var-inits) inits))))
((and (islist exp 4) (symbol? (cadr exp)))
(do ((var-inits (caddr exp) (cdr var-inits))
(vars '())
(inits '()))
((or (not (pair? var-inits))
(not (islist (car var-inits) 2 2))
(not (symbol? (caar var-inits))))
(if var-inits
(error 'let "Illegal form: ~s" exp)
`(letrec ((,(cadr exp)
(lambda ,(reverse vars) ,@(cdddr exp))))
(,(cadr exp) ,@(reverse inits)))))
(set! vars (cons (caar var-inits) vars))
(set! inits (cons (cadar var-inits) inits))))
(else (error 'let "Illegal form: ~s" exp))))
(install-expander 'LET (lambda (x e) (e (let-macro x) e)))
;;; (let* ((var init)...) body) ==> ((lambda (var)
;;; ((lambda (var) body) init))
;;; init)
;;;
;;; LET* is expanded into a set of nested lambda expressions. While this may
;;; make the resulting code more difficult to read, later analysis is eased
;;; because there fewer types of forms to analyze.
(define (LET*-MACRO exp)
(cond ((and (islist exp 3) (islist (cadr exp) 1))
(do ((var-inits (cadr exp) (cdr var-inits))
(vars '())
(inits '()))
((or (not (pair? var-inits))
(not (islist (car var-inits) 2 2))
(not (symbol? (caar var-inits))))
(if var-inits
(error 'let* "Illegal form: ~s" exp)
(car (let*-result vars inits (cddr exp)))))
(set! vars (cons (caar var-inits) vars))
(set! inits (cons (cadar var-inits) inits))))
((and (islist exp 3) (null? (cadr exp)))
`((lambda () ,@(cddr exp))))
(else (error 'let* "Illegal form: ~s" exp))))
(install-expander 'LET* (lambda (x e) (e (let*-macro x) e)))
(define (LET*-RESULT vars inits body)
(cond ((null? vars) body)
(else
(let*-result (cdr vars) (cdr inits)
`(((lambda (,(car vars)) ,@body) ,(car inits)))))))
;;; (letrec ((var init)...) body) ==> ((lambda (var...)
;;; (set! var init) ...)
;;; body)
;;; undefined ...)
;;;
;;; LETREC is expanded into a lambda expression which first binds the vars to
;;; some undefined value and then evalutes the initialization expressions
;;; within the lambda expression. Note that the order of evaluation is
;;; undefined.
(define (LETREC-MACRO exp)
(cond ((and (islist exp 3) (islist (cadr exp) 1))
(do ((var-inits (cadr exp) (cdr var-inits))
(vars '())
(sets '()))
((or (not (pair? var-inits))
(not (islist (car var-inits) 2 2))
(not (symbol? (caar var-inits))))
(if var-inits
(error 'letrec "Illegal form: ~s" exp)
`((lambda ,(reverse vars)
,@(reverse sets)
,@(cddr exp))
,@(map (lambda (v) 0) vars))))
(set! vars (cons (caar var-inits) vars))
(set! sets (cons `(set! ,@(car var-inits)) sets))))
((and (islist exp 3) (null? (cadr exp)))
`((lambda () ,@(cddr exp))))
(else (error 'letrec "Illegal form: ~s" exp))))
(install-expander 'LETREC (lambda (x e) (e (letrec-macro x) e)))
;;; (do ((v1 i1 s1) ...) (test sequence) body ...) ==> (letrec ...)
;;;
;;; Expands a DO form into the corresponding letrec form.
(define (DO-MACRO exp)
(cond ((and (islist exp 3) (islist (cadr exp) 0) (islist (caddr exp) 1))
(let ((let-bindings (cadr exp))
(vars '())
(inits '())
(steps '())
(loop (string->uninterned-symbol "doloop"))
(test (caaddr exp))
(sequence (or (cdaddr exp) '(#f)))
(body (cdddr exp)))
(for-each
(lambda (var-init-step)
(if (islist var-init-step 2 3)
(let* ((var (car var-init-step))
(init (cadr var-init-step))
(step (if (cddr var-init-step)
(caddr var-init-step)
var)))
(set! vars (cons var vars))
(set! steps (cons step steps))
(set! inits (cons init inits)))
(error 'do "Illegal form:" var-init-step)))
(reverse let-bindings))
`(letrec ((,loop (lambda ,vars
(if ,test
(begin ,@sequence)
(begin ,@body
(,loop ,@steps))))))
(,loop ,@inits))))
(else (error 'do "Illegal form: ~s" 'exp))))
(install-expander 'DO (lambda (x e) (e (do-macro x) e)))